import type {ActionType, ProColumns, RequestData} from '@ant-design/pro-table';
import {Popconfirm} from 'antd';
import type {TableProps} from 'antd';
import type {SearchConfig} from '@ant-design/pro-table/lib/components/Form/FormRender';
import BasicTable from '../BasicTable';
import BasicModalForm from '../BasicModalForm';
import type {BasicModalFormRef} from '../BasicModalForm';
import {handleAdd, handleRemove, handleUpdate} from '@/utils/handler';
import {useRef, useState} from 'react';
import {QuestionCircleOutlined} from '@ant-design/icons';
import styles from './index.less';

function BasicFormTable<T>(props: {
  tableRef?: React.MutableRefObject<ActionType | undefined>;
  rowKey?: string;
  title?: React.ReactNode;
  columns: ProColumns<T>[];
  polling?: number | ((dataSource: T[]) => number);
  search?: false | SearchConfig | undefined;
  rowSelection?:
    | (TableProps<T>['rowSelection'] & {
    alwaysShowAlert?: boolean;
  })
    | false;
  params?: AnyFields;
  postData?: (data: T[]) => AnyFields[];
  crud: {
    list: (
      params: PageParams & AnyFields,
      options?: AnyFields | undefined,
    ) => Promise<RequestData<T>>;
    add?: (data: AnyFields) => Promise<Record<string, any>>;
    update?: (data: AnyFields) => Promise<Record<string, any>>;
    remove?: (ids: string) => Promise<Record<string, any>>;
  };
  addForm?: React.ReactNode;
  updateForm?: React.ReactNode;
  renderActions?: (
    actions: JSX.Element[],
    record: T,
    setRecord: (record: T) => void,
  ) => JSX.Element[];
}) {
  const {
    tableRef,
    rowKey = 'id',
    title,
    columns,
    polling,
    search = {labelWidth: 'auto'},
    rowSelection,
    params = {},
    postData,
    addForm,
    updateForm,
    renderActions,
    crud,
  } = props;

  const {list, add, update, remove} = crud;

  const tmpRef = useRef<ActionType>();
  const createRef = useRef<BasicModalFormRef>(null);
  const updateRef = useRef<BasicModalFormRef>(null);
  const [currentRow, setCurrentRow] = useState<T>();

  const actionRef = tableRef || tmpRef;

  const onReload = () => {
    actionRef?.current?.reload?.();
  };

  const basicColumns: ProColumns<T>[] = [
    {
      title: '操作',
      valueType: 'option',
      render: (_, record) => {
        const actions = [];
        if (update && updateForm) {
          actions.push(
            <a
              key="edit"
              onClick={() => {
                setCurrentRow(record);
                updateRef.current?.open();
              }}
            >
              编辑
            </a>,
          );
        }
        if (remove) {
          actions.push(
            <Popconfirm
              key="delete"
              title="确定删除此项？"
              icon={<QuestionCircleOutlined className={styles.removeQuestionIcon}/>}
              onConfirm={async () => {
                await handleRemove(record[rowKey], remove);
                onReload();
                actionRef?.current?.clearSelected?.();
              }}
              okButtonProps={{danger: true}}
              okText="确认"
              cancelText="取消"
            >
              <a className={styles.removeText}>删除</a>
            </Popconfirm>,
          );
        }
        return renderActions ? renderActions(actions, record, setCurrentRow) : actions;
      },
    },
  ];

  return (
    <>
      <BasicTable<T>
        actionRef={actionRef}
        rowKey={rowKey}
        title={title}
        columns={columns.concat(basicColumns)}
        polling={polling}
        search={search}
        rowSelection={rowSelection}
        params={params}
        postData={postData}
        listAction={list}
        removeAction={remove}
        onAdd={() => createRef.current?.open()}
        onReload={onReload}
      />
      {add && (
        <BasicModalForm
          ref={createRef}
          title={`新建${title}`}
          onSubmit={(data) => handleAdd(data, add)}
          onReload={onReload}
        >
          {addForm}
        </BasicModalForm>
      )}
      {update && (
        <BasicModalForm
          ref={updateRef}
          title={`编辑${title}`}
          onSubmit={(data) => handleUpdate({...data, [rowKey]: currentRow?.[rowKey]}, update)}
          onReload={onReload}
          values={currentRow}
        >
          {updateForm}
        </BasicModalForm>
      )}
    </>
  );
}

export default BasicFormTable;
